package cn.doitedu.web_mock;

import org.junit.Test;
import org.roaringbitmap.longlong.Roaring64Bitmap;

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.Iterator;

/**
 * @Author: 深似海
 * @Site: <a href="www.51doit.com">多易教育</a>
 * @QQ: 657270652
 * @Date: 2024/3/8
 * @Desc: 学大数据，上多易教育
 * 模拟规则管理平台的功能
 *
 **/
public class RuleManagement {


    @Test
    public void addRuleForModel02() throws IOException, SQLException {

        String modelCode = "package cn.doitedu.demo7;\n" +
                "\n" +
                "import cn.doitedu.beans.UserAction;\n" +
                "import com.alibaba.fastjson.JSON;\n" +
                "import com.alibaba.fastjson.JSONObject;\n" +
                "import org.apache.flink.api.common.functions.RuntimeContext;\n" +
                "import org.apache.flink.api.common.state.ValueState;\n" +
                "import org.apache.flink.api.common.state.ValueStateDescriptor;\n" +
                "import org.apache.flink.util.Collector;\n" +
                "import org.roaringbitmap.longlong.Roaring64Bitmap;\n" +
                "\n" +
                "import java.io.IOException;\n" +
                "\n" +
                "/**\n" +
                " * @Author: 深似海\n" +
                " * @Site: <a href=\"www.51doit.com\">多易教育</a>\n" +
                " * @QQ: 657270652\n" +
                " * @Date: 2024/3/8\n" +
                " * @Desc: 学大数据，上多易教育\n" +
                " * <p>\n" +
                " * 模型2规则示例：\n" +
                " * 静态画像条件：\n" +
                " * age>10,gender=male\n" +
                " * 动态画像统计条件：\n" +
                " * X>=3次\n" +
                " * 触发条件：\n" +
                " * Y行为\n" +
                " * <p>\n" +
                " * 参数模板：\n" +
                "{\n" +
                "\"rule_id\":\"rule-m02-004\",\n" +
                "\"static_profile_conditions\":[\n" +
                "{\n" +
                "\"tag_name\":\"age\",\n" +
                "\"compare_type\":\">\",\n" +
                "\"compare_value\":10\n" +
                "},\n" +
                "{\n" +
                "\"tag_name\":\"gender\",\n" +
                "\"compare_type\":\"=\",\n" +
                "\"compare_value\":\"male\"\n" +
                "}\n" +
                "],\n" +
                "\"realtime_statistic_conditions\":{\n" +
                "\"event_id\":\"X\",\n" +
                "\"min_count\":3\n" +
                "},\n" +
                "\"trigger_event_id\":\"Y\"\n" +
                "}\n" +
                " **/\n" +
                "public class RuleModelCalculator_02 implements RuleCalculator {\n" +
                "\n" +
                "    private String ruleId;\n" +
                "    Roaring64Bitmap preSelectBitmap;\n" +
                "    ValueState<Integer> state;\n" +
                "\n" +
                "    JSONObject paramJsonObject;\n" +
                "    JSONObject message;\n" +
                "\n" +
                "    @Override\n" +
                "    public void init(RuntimeContext runtimeContext, RuleMeta ruleMeta) throws IOException {\n" +
                "\n" +
                "\n" +
                "        String ruleParamJson = ruleMeta.getRule_param_json();\n" +
                "\n" +
                "        this.paramJsonObject = JSON.parseObject(ruleParamJson);\n" +
                "        this.ruleId = paramJsonObject.getString(\"rule_id\");\n" +
                "\n" +
                "        this.message = new JSONObject();\n" +
                "        message.put(\"rule_id\",ruleId);\n" +
                "\n" +
                "        this.preSelectBitmap = ruleMeta.getPreSelectBitmap();\n" +
                "\n" +
                "        state = runtimeContext.getState(new ValueStateDescriptor<Integer>(ruleId + \"-cnt\", Integer.class));\n" +
                "    }\n" +
                "\n" +
                "    @Override\n" +
                "    public void calc(UserAction userAction, Collector<String> out) throws IOException {\n" +
                "\n" +
                "        // 判断该行为人，是否属于满足静态画像条件的人[从bitmap中判断即可]\n" +
                "        if(!preSelectBitmap.contains(userAction.getUser_id())) return;\n" +
                "\n" +
                "\n" +
                "        String eventId = userAction.getEvent_id();\n" +
                "\n" +
                "        JSONObject realtimeStatisticConditions = paramJsonObject.getJSONObject(\"realtime_statistic_conditions\");\n" +
                "        String targetEventId = realtimeStatisticConditions.getString(\"event_id\");\n" +
                "        int minCount = realtimeStatisticConditions.getIntValue(\"min_count\");\n" +
                "\n" +
                "        // 动态画像条件统计\n" +
                "        if(eventId.equals(targetEventId)){\n" +
                "            state.update( state.value()==null? 1: state.value()+1 );\n" +
                "        }\n" +
                "\n" +
                "\n" +
                "\n" +
                "        // 触发判断\n" +
                "        String triggerEventId = paramJsonObject.getString(\"trigger_event_id\");\n" +
                "        if(eventId.equals(triggerEventId)){\n" +
                "            if(state.value() != null && state.value()>= minCount){\n" +
                "                message.put(\"user_id\",userAction.getUser_id());\n" +
                "                message.put(\"hit_time\",userAction.getAction_time());\n" +
                "                out.collect(message.toJSONString());\n" +
                "            }\n" +
                "        }\n" +
                "    }\n" +
                "\n" +
                "    @Override\n" +
                "    public String ruleId() {\n" +
                "        return ruleId;\n" +
                "    }\n" +
                "\n" +
                "\n" +
                "}\n";


        String ruleParamJson = "{\n" +
                "\"rule_id\":\"rule-m02-004\",\n" +
                "\"static_profile_conditions\":[\n" +
                "{\n" +
                "\"tag_name\":\"age\",\n" +
                "\"compare_type\":\">=\",\n" +
                "\"compare_value\":20\n" +
                "},\n" +
                "{\n" +
                "\"tag_name\":\"gender\",\n" +
                "\"compare_type\":\"regexp_match\",\n" +
                "\"compare_value\":\"^ma.*\"\n" +
                "}\n" +
                "],\n" +
                "\"realtime_statistic_conditions\":{\n" +
                "\"event_id\":\"X\",\n" +
                "\"min_count\":3\n" +
                "},\n" +
                "\"trigger_event_id\":\"Y\"\n" +
                "}";


        // 假设已经查询完用户画像库，得到了1,2,3,4,5,8,9,10用户满足条件
        Iterator<Long> iterator = Arrays.asList(1L, 2L, 3L, 4L, 5L, 8L, 9L, 10L).iterator();


        Roaring64Bitmap bitmap = Roaring64Bitmap.bitmapOf();
        // 迭代查询结果
        while(iterator.hasNext()){
            long userId = iterator.next();
            bitmap.add(userId);
        }

        // 把bitmap序列化成字节数组
        ByteArrayOutputStream baout = new ByteArrayOutputStream();
        DataOutputStream dout = new DataOutputStream(baout);
        bitmap.serialize(dout);
        byte[] bitmapBytes = baout.toByteArray();


        Connection connection = DriverManager.getConnection("jdbc:mysql://doitedu:3306/doit46", "root", "root");

        PreparedStatement stmt = connection.prepareStatement("insert into rule_meta values(?,?,?,?,?,?,?,?)");
        stmt.setString(1,"rule-m02-004");
        stmt.setString(2,"m02");
        stmt.setString(3,ruleParamJson);
        stmt.setString(4,"deepAsSea");
        stmt.setInt(5,1);
        stmt.setBytes(6,bitmapBytes);
        stmt.setLong(7,-1L);
        stmt.setString(8,modelCode);

        stmt.execute();

        stmt.close();
        connection.close();

    }


    @Test
    public void addRuleForModel04() throws IOException, SQLException {

        String ruleParamJson = "{\n" +
                "  \"rule_id\": \"rule-m04-003\",\n" +
                "  \"static_profile_conditions\":[\n" +
                "    {\n" +
                "      \"tag_name\":\"age\",\n" +
                "      \"compare_type\":\">\",\n" +
                "      \"compare_value\":20\n" +
                "    },\n" +
                "    {\n" +
                "      \"tag_name\":\"value_level\",\n" +
                "      \"compare_type\":\"=\",\n" +
                "      \"compare_value\":\"C\"\n" +
                "    }\n" +
                "  ],\n" +
                "  \"trigger_condition\":{\n" +
                "    \"event_id\":\"E\",\n" +
                "    \"property_name\":[\"p0\",\"p1\"],\n" +
                "    \"calc_expression\":\"p0+p1*10\",\n" +
                "    \"target_min_value\":150\n" +
                "  }\n" +
                "\n" +
                "}";


        // 假设已经查询完用户画像库，得到了1,2,3,4,5,8,9,10用户满足条件
        Iterator<Long> iterator = Arrays.asList(1L, 3L, 5L, 7L, 9L).iterator();


        Roaring64Bitmap bitmap = Roaring64Bitmap.bitmapOf();
        // 迭代查询结果
        while(iterator.hasNext()){
            long userId = iterator.next();
            bitmap.add(userId);
        }

        // 把bitmap序列化成字节数组
        ByteArrayOutputStream baout = new ByteArrayOutputStream();
        DataOutputStream dout = new DataOutputStream(baout);
        bitmap.serialize(dout);
        byte[] bitmapBytes = baout.toByteArray();


        Connection connection = DriverManager.getConnection("jdbc:mysql://doitedu:3306/doit46", "root", "root");

        PreparedStatement stmt = connection.prepareStatement("insert into rule_meta values(?,?,?,?,?,?)");
        stmt.setString(1,"rule-m04-003");
        stmt.setString(2,"m04");
        stmt.setString(3,ruleParamJson);
        stmt.setString(4,"deepAsSea");
        stmt.setInt(5,1);
        stmt.setBytes(6,bitmapBytes);

        stmt.execute();

        stmt.close();
        connection.close();

    }


}
